package webjoch.methods;

import java.util.ArrayList;

import org.rsbuddy.tabs.Inventory;

import webjoch.misc.Constants;
import webjoch.misc.Functions;

import com.rsbuddy.script.methods.Calculations;
import com.rsbuddy.script.methods.Game;
import com.rsbuddy.script.methods.GroundItems;
import com.rsbuddy.script.methods.Mouse;
import com.rsbuddy.script.methods.Npcs;
import com.rsbuddy.script.methods.Players;
import com.rsbuddy.script.methods.Skills;
import com.rsbuddy.script.task.Task;
import com.rsbuddy.script.util.Filter;
import com.rsbuddy.script.wrappers.GroundItem;
import com.rsbuddy.script.wrappers.Npc;

/**
 * 
 * @author Webjoch
 *
 */
public class Food{
	/**
	 * Eat food from inventory
	 * @param minFood minimum food item to eat (0 - 9)
	 */
	public static void eat(int minFood){
		for (int i = minFood<0 ? 0 : minFood; i < Constants.FOOD.length; i++){
			 if (Inventory.contains(Constants.FOOD[i])){
				 Npc inCombatNpc = Npcs.getNearest(new Filter<Npc>(){
					public boolean accept(Npc npc) {
						return Functions.inArray(Constants.ENEMIES, npc.getId()) && Calculations.distanceTo(npc) < 3 && npc.isInCombat();
					}
				 });
				 Mouse.setSpeed(2);
				 Inventory.getItem(Constants.FOOD[i]).interact("Eat");
				 Task.sleep(1000, 1500);
				 if (inCombatNpc != null && Players.getLocal().isInCombat()) inCombatNpc.interact("Attack");
				 Mouse.setSpeed(4);
				 break;
			 }
		 }
	}
	
	/**
	 * Eat food based on the players life points
	 */
	public static void eat(){
		int damage = getTotalLifePoints() - getLifePoints();
		if (damage > 70){
			eat(9 - (int) Math.ceil(damage / 30));
		}
	}
	
	/**
	 * Drops lowest food first
	 * @param amount amount of food to drop
	 */
	public static void dropFood(int amount){
		for (int i = 0; i < amount; i++){
			for (int i2 = 0; i2 < Constants.FOOD.length; i2++){
				if (Inventory.contains(Constants.FOOD[9-i2])){
					Inventory.getItem(Constants.FOOD[9-i2]).interact("Drop");
					break;
				}
			}
		}
	}
	
	/**
	 * Takes food in the local room based on inventory space
	 * @return returns true if there is food to take
	 */
	public static boolean takeFood(){
		ArrayList<GroundItem> selectedFood = new ArrayList<GroundItem>();
		for (int i = 0; i < Constants.FOOD.length; i++){
			if (Inventory.getCount() > 27 - i * 2 || i > 9) break;
			GroundItem[] foods = getFoodFromTier(i);
			if (foods.length > 0){
				for (GroundItem food : foods){
					if (Inventory.getCount() > 27 - i * 2) break;
					i++;
					selectedFood.add(food);
				}
			}
		}
		if (selectedFood.size() > 0){
			GroundItem nearestFood = null;
			for (GroundItem food : selectedFood){
				if (nearestFood == null) nearestFood = food;
				if (Calculations.distanceTo(food.getLocation()) < Calculations.distanceTo(nearestFood.getLocation())){
					nearestFood = food;
				}
			}
			Items.interact(nearestFood, "Take");
			Task.sleep(800, 1500);
			return true;
		}
		return false;
	}
	
	/**
	 * Get food on ground with highest food as priority
	 * @param amount max amount of food to return
	 * @return an array of food GroundItems
	 */
	public static GroundItem[] getGroundFood(int amount){
		ArrayList<GroundItem> selectedFood = new ArrayList<GroundItem>();
		o:
		for (int i = 0; i < Constants.FOOD.length; i++){
			GroundItem[] foods = getFoodFromTier(i);
			if (foods.length > 0){
				for (GroundItem food : foods){
					selectedFood.add(food);
					if (selectedFood.size() >= amount){
						break o;
					}
				}
			}
		}
		return selectedFood.toArray(new GroundItem[selectedFood.size()]);
	}
	
	/**
	 * Gets the players lifepoints
	 * @return the players lifepoints
	 */
	public static int getLifePoints(){
		return Game.getPlayerLifePoints();
	}
	
	/**
	 * Gets the player maxed lifepoints
	 * @return the players maxed lifepoints
	 */
	public static int getTotalLifePoints(){
		return Skills.getCurrentLevel(Skills.CONSTITUTION) * 10;
	}
	
	public static int getLifePointPercent(){
		return (int) ((double) getLifePointPercent() / getTotalLifePoints()) * 100;
	}
	
	private static GroundItem[] getFoodFromTier(final int tier){
		return GroundItems.getLoaded(new Filter<GroundItem>(){
			public boolean accept(GroundItem item){
				return Rooms.getLocalRoom().getArea().contains(item.getLocation()) && Constants.FOOD[tier] == item.getItem().getId();
			}
		});
	}
}
